#include "Page.h"
DateTime myDT=DateTime();

//@author A0073611N
vector<string> explode(const string& str, const char& ch) {
    string next;
    vector<string> result;

    // For each character in the string
    for (string::const_iterator it = str.begin(); it != str.end(); it++) {
        // If we've hit the terminal character
        if (*it == ch) {
            // If we have some characters accumulated
            if (!next.empty()) {
                // Add them to the result vector
                result.push_back(next);
                next.clear();
            }
        } else {
            // Accumulate the next character into the sequence
            next += *it;
        }
    }
    if (!next.empty())
         result.push_back(next);
    return result;
}

//@author U095387X
void Page::initialize(User *UIUser, ActionManager *UIActionManager){
	_curUser = UIUser;
	_curActionManager = UIActionManager;
}

//@author A0073611N
int Page::showPage(e_state curState, e_category mCategory, e_method mMethod, e_dateRange _mDateRange){

	int callMainMenu = 0;

	switch(curState)
	{
	case recordNewExpense:
		addExpense(mCategory, mMethod);
		break;

	case recordNewLoan:
		addLoan();
		break;

	case recordNewWish:
		addWish();
		break;

	case recordNewIncome:
		addIncome();
		break;

	case readExpense:
		callMainMenu = printList(_mDateRange);
		break;

	case readLoan:
		callMainMenu = printLoanList(_mDateRange);
		break;

	case readWish:
		callMainMenu = printWishList(_mDateRange);
		break;

	case readIncome:
		callMainMenu = printIncomeList(_mDateRange);
		break;

	case showReport:
		callMainMenu = printReport(_mDateRange);
		break;

	case Undo:
		undoAction();
		break;

	case changeUser:
		updateUser();
		break;

	case importReport:
		impReport();
		break;
	}

	return callMainMenu;
}

//@author A0073611N
int Page::categoryEnumtoInt(e_category category)
{
	switch(category)
	{
	case 0:
		return 1;
	case 1:
		return 2;
	case 2:
		return 3;
	default:
		return 4;
	}
}

//@author A0073611N
int Page::methodEnumtoInt(e_method method)
{
	switch(method)
	{
	default:
		return 1;
	case 1:
		return 2;
	case 2:
		return 3;
	}
}

//@author A0073611N
string Page::categoryEnumtoString(e_category category)
{
	switch(category)
	{
	case 0:
		return "Food";
	case 1:
		return "Transportation";
	case 2:
		return "Entertainment";
	default:
		return "Others";
	}
}

//@author A0073611N
string Page::methodEnumtoString(e_method method)
{
	switch(method)
	{
	default:
		return "Cash";
	case 1:
		return "CreditCard";
	case 2:
		return "DebitCard";
	}
}

//@author A0073611N
e_category Page::categoryInttoEnum(int s_cat)
{
	e_category category;
	switch(s_cat)
	{
	case 0:
		category=Food;
		break;
	case 1:
		category=Transportation;
		break;
	case 2:
		category=Entertainment;
		break;
	case 3:
		category=Others;
		break;
	}
	return category;
}

//@author A0073611N
e_method Page::methodInttoEnum(int s_met)
{
	e_method method;
	switch(s_met)
	{
	case 0:
		method=Cash;
		break;
	case 1:
		method=CreditCard;
		break;
	case 2:
		method=DebitCard;
		break;
	}
	return method;
}

//@author A0073611N
void Page::addExpense(e_category mCategory, e_method mMethod)
{
	string input,name,remark;
	double amount;
	time_t timeOfRecord=1,inputTime=0;
	string date;

	printf ("Enter the Name:\n");
	getline(cin,name);

	printf ("\nEnter the Amount:\n");
	getline(cin,input);
	istringstream in(input);
	in >>amount;

	printf ("\nEnter the Time of Record: <DDMMYYYY>\n");
	while(inputTime<timeOfRecord)
	{
		getline(cin,date);
		try{
			timeOfRecord=myDT.getTimeT(date);
		}
		catch (string e)
		{
			cout << "Error: " << e << endl;
			cout << "x : return to main menu" << endl;
			return;
		}
		time(&inputTime);
		if(inputTime<timeOfRecord)
			printf ("Future expense does not exist\nPlease enter again\n");
	}

	printf ("\nEnter the Remark:\n");
	getline(cin,remark);

	time_t timeExpense = timeOfRecord;
	time_t rawTime;
	time(&rawTime);
	struct tm * timeInfo;
	struct tm * rawTimeInfo;
	timeInfo = localtime(&timeExpense);
	int expenseMonth = timeInfo->tm_mon;
	int expenseYear = timeInfo->tm_year;
	rawTimeInfo = localtime(&rawTime);
	int thisMonth = rawTimeInfo->tm_mon;
	int thisYear = rawTimeInfo->tm_year;
	int monthPass =	(thisYear - expenseYear)*12 + (thisMonth - expenseMonth);

	if(monthPass == 0 && (amount > _curUser->getCashOnHand() || amount > (_curUser->getBudget() - _curUser->getTotalExpense()))){
		printf("\nYou have not enough budget to add in this expense!\n");
		cout << "x : return to main menu" << endl;
	}
	else{
		Expense exp1(name,amount,timeOfRecord,inputTime,mMethod,mCategory,remark);

		printf("\nThe following expense has been recorded to the database\n");
		cout<<name<<" "<<floor(amount * 100 + 0.5) / 100<<" "<<timeOfRecord<<" "<<categoryEnumtoString(mCategory)<<" "<<methodEnumtoString(mMethod)<<" "<<remark<<endl<<endl;
		_curUser->addExpense(exp1);
		_curActionManager->addExpenseAction(exp1,Add);
		cout << "x : return to main menu" << endl;
	}
}

//@author A0073611N
// the expense printed is not date inclusive, the result is now startTime < printedInfo <= endTime
int Page::printList(e_dateRange _mDateRange)
{
	string date,input,name=" ";
	double amount=0;
	time_t timeOfRecord=0;
	time_t timeInput=0;
	e_method method=Cash;
	e_category category=Food;
	string s_method;
	string s_category;
	string remark=" ";
	time_t startTime,endTime;
	list<Expense> mylist;
	Expense exp(name,amount,timeOfRecord,timeInput,method,category,remark);
	int number;

	switch(_mDateRange)
	{
	case 0:
		{
			printf("Please enter the date <DDMMYYYY>\n");
			getline(cin,date);
			try
			{
				startTime=myDT.getTimeT(date)-86400;
				endTime=myDT.getTimeT(date);
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			break;
		}
	case 1:
		{
			printf("Please enter the month <MMYYYY>\n");
			getline(cin,date);
			try
			{
				startTime=myDT.getTimeT("01"+date)-86400;
				endTime=myDT.getNextMonthYear(date)-86400;
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			break;
		}
	case 2:
		{
			printf("Please enter the start time <DDMMYYYY>\n");
			getline(cin,date);
			try{
				startTime=myDT.getTimeT(date)-86400;
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			printf("Please enter the end time <DDMMYYYY>\n");
			getline(cin,date);
			try{
				endTime=myDT.getTimeT(date);
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			break;
		}
	}

	mylist=_curUser->getUserAccount()->readExpense(startTime, endTime);
	if (mylist.empty())
		printf("No record found, press x to main menu\n");
	else
	{
		printf("------------------------------------------------------------------\n");
		printf("                           Report                                 \n");
		cout<<"          From:"<<myDT.getDate(startTime+86400)<<"               To:"<<myDT.getDate(endTime)<<endl;
		printf("------------------------------------------------------------------\n");
		printf("<no.> <name> <amount> <time> <category> <method> <remark>\n");
		number=0;

		for(list<Expense>::iterator it=mylist.begin();it != mylist.end(); ++it)
		{
			name=it->getName();
			amount=it->getAmount();
			timeOfRecord=it->getTimeOfRecord();
			s_method=methodEnumtoString(it->getMethod());
			s_category=categoryEnumtoString(it->getCategory());
			remark=it->getRemark();
			if (number!=mylist.size())
				number++;
			cout<<number<<"\t"<<name<<"\t"<<floor(amount * 100 + 0.5) / 100<<"\t"<<myDT.getDate(timeOfRecord)<<"\t"<<s_category<<"\t"<<s_method<<"\t"<<remark<<endl;
		}
		printf("------------------------------------------------------------------\n");
		cout<<endl;

		printf("u : update expense, d : delete expense, x : return to main menu\n");
		do{
			getline(cin,input);
		}while(input!="d" && input!="u" && input!="x");
		if(input=="d")
			delExpense(mylist);
		else if(input=="u")
			upExpense(mylist);
		else if(input=="x")
			return -1;
	}
	return 0;
}

//@author A0106829Y
void Page::delExpense(list<Expense> mylist)
{
	string input,name=" ";
	double amount=0;
	time_t timeOfRecord=0;
	time_t timeInput=0;
	e_method method=Cash;
	e_category category=Food;
	string s_method;
	string s_category;
	string remark=" ";
	Expense exp(name,amount,timeOfRecord,timeInput,method,category,remark);
	int choice,i;

	printf("\nPleaase select the expense you want to delete:\n");
	getline(cin, input);
	choice=atoi(input.c_str());
	list<Expense>::iterator it2=mylist.begin();
	for(i=0;i<choice-1; i++){
		if(it2 == mylist.end()){
			cout << "x : return to main menu" << endl;
			return;
		}
		it2++;
	}

	exp=*it2;
	_curUser->deleteExpense(exp);
	_curActionManager->addExpenseAction(exp,Delete);

	printf("\nThis expense is deleted:\n");
	cout<<exp.getName()<<"\t"<<floor(exp.getAmount() * 100 + 0.5) / 100<<"\t"<<myDT.getDate(exp.getTimeOfRecord())<<"\t"<<categoryEnumtoString(exp.getCategory())<<"\t"<<methodEnumtoString(exp.getMethod())<<"\t"<<exp.getRemark()<<endl;

}

//@author U095387X
void Page::undoAction()
{	
	string input;
	printf ("\nConfirm Undo? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");

	if(input == "Y" ){
		_curActionManager->undoAction();
		printf("Undo function activated!\n");
	}
	cout << "x : return to main menu" << endl;
}

//@author A0106829Y
void Page::addWish()
{
	string input,name;
	double amount;
	time_t expectedDate,inputTime;
	string date;

	cout<<"Enter the Name:\n";
	getline(cin,name);

	printf ("\nEnter the Amount:\n");
	getline(cin,input);
	istringstream in(input);
	in >>amount;

	printf ("\nEnter the Expected Date <DDMMYYYY>:\n");
	getline(cin,date);

	try{
		expectedDate=myDT.getTimeT(date);
	}
	catch (string e)
	{
		cout << "Error: " << e << endl;
		cout << "x : return to main menu" << endl;
		return;
	}
	time(&inputTime);

	Wish wish1(name, amount, inputTime, expectedDate);

	printf("\nThe following wish has been recorded to the database\n");
	cout<<name<<" "<<floor(amount* 100 + 0.5) / 100<<" "<<expectedDate <<endl<<endl;
	_curUser->addWish(wish1);
	_curActionManager->addWishAction(wish1,Add);
	cout << "x : return to main menu" << endl;
}

//@author A0073611N
// the wish printed is not date inclusive, the result is now startTime < printedInfo <= endTime, no result when startTime == endTime
int Page::printWishList(e_dateRange _mDateRange)
{
	string input,date,name=" ";
	double amount=0;
	time_t expectedDate=0;
	time_t timeInput=0;
	list<Wish> mylist;
	Wish wish(name,amount,timeInput,expectedDate);
	int number=0;

	mylist=_curUser->getUserAccount()->readWish(); 
	if (mylist.empty())
		printf("No record found, press x to main menu\n");
	else
	{
		printf("------------------------------------------------------------------\n");
		printf("                           Report                                 \n\n");

		printf("------------------------------------------------------------------\n");
		printf("<no.> <item> <amount> <expected date>\n");

		//Wish(name,amount,timeOfInput,expectedDate);
		for(list<Wish>::iterator it=mylist.begin();it != mylist.end(); ++it)
		{
			name=it->getName();
			amount=it->getAmount();
			expectedDate=it->getExpectedDate();
			if (number!=mylist.size())
				number++;
			cout<<number<<"\t"<<name<<"\t"<<floor(amount* 100 + 0.5) / 100<<"\t"<<myDT.getDate(expectedDate)<<endl;
		}
		printf("------------------------------------------------------------------\n");
		cout<<endl;

		printf("u : update wish, d : delete wish, x : return to main menu\n");
		do{
			getline(cin,input);
		}while(input!="d" && input!="u" && input!="x");
		if(input=="d")
			delWish(mylist);
		else if(input=="u")
			upWish(mylist);
		else if(input=="x")
			return -1;
	}
	return 0;
}

//@author A0106829Y
void Page::delWish(list<Wish> mylist)
{
	string input,date,name=" ";
	double amount=0;
	time_t expectedDate=0;
	time_t timeInput=0;
	Wish wish(name,amount,timeInput,expectedDate);
	int choice,i;

	printf("\nPleaase select the wish you want to delete:\n");
	getline(cin, input);
	choice=atoi(input.c_str());
	list<Wish>::iterator it2=mylist.begin();
	for(i=0;i<choice-1; i++){
		if(it2 == mylist.end()){
			cout << "x : return to main menu" << endl;
			return;
		}
		it2++;
	}

	wish=*it2;
	_curUser->deleteWish(wish);
	_curActionManager->addWishAction(wish,Delete);

	printf("\nThis wish is deleted:\n");
	cout<<wish.getName()<<"\t"<<floor(wish.getAmount()*100+0.5)/100<<"\t"<<myDT.getDate(wish.getExpectedDate())<<endl;
	cout << "x : return to main menu" << endl;
}

//@author A0106829Y
void Page::addLoan()
{
	string input,name,remark;
	double amount;
	time_t timeOfRecord,inputTime;
	string date;

	printf ("Enter the Name:\n");
	getline(cin,name);

	printf ("\nEnter the Amount:\n");
	getline(cin,input);
	istringstream in(input);
	in >>amount;

	printf ("\nEnter the Time of Payment: <DDMMYYYY>\n");
	getline(cin,date);

	printf ("\nEnter the Remark:\n");
	getline(cin,remark);

	try{
		timeOfRecord=myDT.getTimeT(date);
	}
	catch (string e)
	{
		cout << "Error: " << e << endl;
		cout << "x : return to main menu" << endl;
		return;
	}
	time(&inputTime);

	Loan loan1(name,amount,timeOfRecord,inputTime,remark);

	printf("\nThe following loan has been recorded to the database\n");
	cout<<name<<" "<<floor(amount* 100 + 0.5) / 100<<" "<<timeOfRecord<<" "<<remark<<endl<<endl;
	_curUser->addLoan(loan1);
	_curActionManager->addLoanAction(loan1,Add);
	cout << "x : return to main menu" << endl;
}

//@author A0073611N
// the loan printed is not date inclusive, the result is now startTime < printedInfo <= endTime
int Page::printLoanList(e_dateRange _mDateRange)
{
	string date,input,name=" ";
	double amount=0;
	time_t timeOfRecord=0;
	time_t timeInput=0;
	string remark=" ";
	time_t startTime,endTime;
	list<Loan> mylist;
	Loan loan(name,amount,timeOfRecord,timeInput,remark);
	int number=0;

	switch(_mDateRange)
	{
	case 0:
		{
			printf("Please enter the date <DDMMYYYY>\n");
			getline(cin,date);
			try{
				startTime=myDT.getTimeT(date)-86400;
				endTime=myDT.getTimeT(date);
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			break;
		}
	case 1:
		{
			printf("Please enter the month <MMYYYY>\n");
			getline(cin,date);
			try{
				startTime=myDT.getTimeT("01"+date)-86400;
				endTime=myDT.getNextMonthYear(date)-86400;
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			break;
		}
	case 2:
		{
			printf("Please enter the start time <DDMMYYYY>\n");
			getline(cin,date);
			try{
				startTime=myDT.getTimeT(date)-86400;
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			printf("Please enter the end time <DDMMYYYY>\n");
			getline(cin,date);
			try{
				endTime=myDT.getTimeT(date);
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			break;
		}
	}

	mylist=_curUser->getUserAccount()->readLoan(startTime, endTime);
	if (mylist.empty())
		printf("No record found, press x to main menu\n");
	else
	{
		printf("------------------------------------------------------------------\n");
		printf("                           Report                                 \n");
		cout<<"          From:"<<myDT.getDate(startTime+86400)<<"               To:"<<myDT.getDate(endTime)<<endl;
		printf("------------------------------------------------------------------\n");
		printf("<no.> <item> <amount> <payment date> <remark>\n");

		for(list<Loan>::iterator it=mylist.begin();it != mylist.end(); ++it)
		{
			name=it->getName();
			amount=it->getAmount();
			timeOfRecord=it->getTimeOfRecord();
			remark=it->getRemark();
			if (number!=mylist.size())
				number++;
			cout<<number<<"\t"<<name<<"\t"<<floor(amount* 100 + 0.5) / 100<<"\t"<<myDT.getDate(timeOfRecord)<<"\t"<<remark<<endl;
		}
		printf("------------------------------------------------------------------\n");
		cout<<endl;

		printf("u : update loan, d : delete loan, x : return to main menu\n");
		do{
			getline(cin,input);
		}while(input!="d" && input!="u" && input!="x");
		if(input=="d")
			delLoan(mylist);
		else if(input=="u")
			upLoan(mylist);
		else if(input=="x")
			return -1;
	}
	return 0;
}


//@author A0106829Y
void Page::delLoan(list<Loan> mylist)
{
	string date,input,name=" ";
	double amount=0;
	time_t timeOfRecord=0;
	time_t timeInput=0;
	string remark=" ";
	Loan loan(name,amount,timeOfRecord,timeInput,remark);
	int choice,i;

	printf("\nPleaase select the loan you want to delete:\n");
	getline(cin, input);
	choice=atoi(input.c_str());
	list<Loan>::iterator it2=mylist.begin();
	for(i=0;i<choice-1; i++){
		if(it2 == mylist.end()){
			cout << "x : return to main menu" << endl;
			return;
		}
		it2++;
	}
	loan=*it2;
	_curUser->deleteLoan(loan);
	_curActionManager->addLoanAction(loan,Delete);

	printf("\nThis loan is deleted:\n");
	cout<<loan.getName()<<"\t"<<floor(loan.getAmount()*100 +0.5)/100<<"\t"<<myDT.getDate(loan.getTimeOfRecord())<<"\t"<<loan.getRemark()<<endl;
	cout << "x : return to main menu" << endl;
}

//@author A0073611N
void Page::upExpense(list<Expense> mylist)
{
	string date,input,name=" ";
	double amount=0;
	time_t timeOfRecord=0;
	time_t timeInput=0;
	e_method method=Cash;
	e_category category=Food;
	string s_method;
	string s_category;
	string remark=" ";
	Expense exp(name,amount,timeOfRecord,timeInput,method,category,remark);
	int choice,i;
	int s_cat,s_met;

	printf("\nPleaase select the expense you want to update:\n");
	getline(cin, input);
	choice=atoi(input.c_str());
	list<Expense>::iterator it2=mylist.begin();
	for(i=0;i<choice-1; i++){
		if(it2 == mylist.end()){
			cout << "x : return to main menu" << endl;
			return;
		}
		it2++;
	}

	exp=*it2;
	name=it2->getName();
	amount=it2->getAmount();
	timeOfRecord = it2->getTimeOfRecord();
	timeInput =  it2->getTimeOfInput();
	s_method=methodEnumtoString(it2->getMethod());
	s_met=methodEnumtoInt(it2->getMethod());
	s_category=categoryEnumtoString(it2->getCategory());
	s_cat=categoryEnumtoInt(it2->getCategory());
	remark=it2->getRemark();

	printf("\nThis expense is chosen:\n");
	cout<<exp.getName()<<" "<<floor(exp.getAmount()*100 +0.5)/100<<" "<<myDT.getDate(exp.getTimeOfRecord())<<" "<<categoryEnumtoString(exp.getCategory())<<" "<<methodEnumtoString(exp.getMethod())<<" "<<exp.getRemark()<<endl;

	printf("\nUpdate Name? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Name: \n");
		getline(cin,name);
	}

	printf("\nUpdate Amount? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Amount: \n");
		getline(cin,input);
		istringstream in(input);
		in >>amount;
	}

	printf("\nUpdate Category? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Category (Food=0, Transportation=1, Entertainment=2, Others=3) : \n");
		getline(cin,input);
		istringstream in(input);
		in>>s_cat;
	}

	printf("\nUpdate Method? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Method  (Cash=0, Creditcard=1, Debitcard=2) : \n");
		getline(cin,input);
		istringstream in(input);
		in>>s_met;
	}

	printf("\nUpdate Remark?\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Remark: \n");
		getline(cin,remark);
	}

	Expense New_exp(name,amount,timeOfRecord,timeInput,methodInttoEnum(s_met),categoryInttoEnum(s_cat),remark);

	time_t timeExpense = timeOfRecord;
	time_t rawTime;
	time(&rawTime);
	struct tm * timeInfo;
	struct tm * rawTimeInfo;
	timeInfo = localtime(&timeExpense);
	int expenseMonth = timeInfo->tm_mon;
	int expenseYear = timeInfo->tm_year;
	rawTimeInfo = localtime(&rawTime);
	int thisMonth = rawTimeInfo->tm_mon;
	int thisYear = rawTimeInfo->tm_year;
	int monthPass =	(thisYear - expenseYear)*12 + (thisMonth - expenseMonth);

	if(monthPass == 0 && ((New_exp.getAmount() - exp.getAmount() ) > _curUser->getCashOnHand() || ( New_exp.getAmount() - exp.getAmount() ) > (_curUser->getBudget() - _curUser->getTotalExpense()))){
		printf("\nYou have not enough budget to update this expense!\n");
		cout << "x : return to main menu" << endl;
	}
	else{

	_curUser->updateExpense(exp,New_exp);
	_curActionManager->addExpenseAction(exp,Update);
	_curActionManager->addExpenseAction(New_exp,Update);

	printf("\nThis expense is updated:\n");
	cout<<New_exp.getName()<<" "<<floor(New_exp.getAmount()*100+0.5)/100<<" "<<myDT.getDate(New_exp.getTimeOfRecord())<<" "<<categoryEnumtoString(New_exp.getCategory())<<" "<<methodEnumtoString(New_exp.getMethod())<<" "<<New_exp.getRemark()<<endl;
	cout << "x : return to main menu" << endl;
	}
}

//@author A0073611N
void Page::upLoan(list<Loan> mylist)
{
	string date,input,name=" ";
	double amount=0;
	time_t timeOfRecord=0;
	time_t timeInput=0;
	string remark=" ";
	Loan loan(name,amount,timeOfRecord,timeInput,remark);
	int choice,i;

	printf("\nPleaase select the loan you want to update:\n");
	getline(cin, input);
	choice=atoi(input.c_str());
	list<Loan>::iterator it2=mylist.begin();
	for(i=0;i<choice-1; i++){
		if(it2 == mylist.end()){
			cout << "x : return to main menu" << endl;
			return;
		}
		it2++;
	}
	loan=*it2;
	name=it2->getName();
	amount=it2->getAmount();
	timeOfRecord=it2->getTimeOfRecord();
	remark=it2->getRemark();
	timeInput=it2->getTimeOfInput();

	printf("\nThis loan is chosen:\n");
	cout<<loan.getName()<<" "<<floor(loan.getAmount()*100+0.5)/100<<" "<<loan.getRemark()<<endl;

	printf("\nUpdate Name? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");

	if(input=="Y")
	{
		printf("\nInput new Name: \n");
		getline(cin,name);
	}

	printf("\nUpdate Amount? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Amount: \n");
		getline(cin,input);
		istringstream in(input);
		in >>amount;
	}

	printf("\nUpdate Remark? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Remark: \n");
		getline(cin,remark);
	}

	Loan new_loan(name,amount,timeOfRecord,timeInput,remark);
	_curUser->updateLoan(loan,new_loan);
	_curActionManager->addLoanAction(loan,Update);
	_curActionManager->addLoanAction(new_loan,Update);

	printf("\nThis loan is updated:\n");
	cout<<new_loan.getName()<<" "<<floor(new_loan.getAmount()*100+0.5)/100<<" "<<myDT.getDate(new_loan.getTimeOfRecord())<<" "<<new_loan.getRemark()<<endl;
	cout << "x : return to main menu" << endl;
}

//@author A0073611N
void Page::upWish(list<Wish> mylist)
{
	string input,date,name=" ";
	double amount=0;
	time_t expectedDate=0;
	time_t timeInput=0;
	Wish wish(name,amount,timeInput,expectedDate);
	int choice,i;

	printf("\nPleaase select the wish you want to update:\n");
	getline(cin, input);
	choice=atoi(input.c_str());
	list<Wish>::iterator it2=mylist.begin();
	for(i=0;i<choice-1; i++){
		if(it2 == mylist.end()){
			cout << "x : return to main menu" << endl;
			return;
		}
		it2++;
	}
	wish=*it2;
	name=it2->getName();
	amount=it2->getAmount();
	expectedDate=it2->getExpectedDate();
	timeInput=it2->getTimeOfInput();

	printf("\nThis wish is chosen:\n");
	cout<<wish.getName()<<" "<<floor(wish.getAmount()*100+0.5)/100<<" "<<wish.getExpectedDate()<<endl;

	printf("\nUpdate Name? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Name: \n");
		getline(cin,name);
	}

	printf("\nUpdate Amount? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Amount: \n");
		getline(cin,input);
		istringstream in(input);
		in >>amount;
	}

	printf("\nUpdate Expected Date? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Date <DDMMYYYY>: \n");
		getline(cin,date);
		expectedDate=myDT.getTimeT(date);
	}

	Wish new_wish(name,amount,expectedDate);
	_curUser->updateWish(wish,new_wish);
	_curActionManager->addWishAction(wish,Update);
	_curActionManager->addWishAction(new_wish,Update);

	printf("\nThis loan is updated:\n");
	cout<<new_wish.getName()<<" "<<floor(new_wish.getAmount()*100+0.5)/100<<" "<<myDT.getDate(new_wish.getExpectedDate())<<endl;
	cout << "x : return to main menu" << endl;
}

//@author A0106829Y
void Page::addIncome()
{
	string input,name,remark;
	double amount;
	time_t timeOfRecord=1,inputTime=0;
	string date;

	printf ("Enter the Name:\n");
	getline(cin,name);

	printf ("\nEnter the Amount:\n");
	getline(cin,input);
	istringstream in(input);
	in >>amount;

	printf ("\nEnter the Time of Record: <DDMMYYYY>\n");
	while(inputTime<timeOfRecord)
	{
		getline(cin,date);
		try{
			timeOfRecord=myDT.getTimeT(date);
		}
		catch (string e)
		{
			cout << "Error: " << e << endl;
			cout << "x : return to main menu" << endl;
			return;
		}
		time(&inputTime);
		if(inputTime<timeOfRecord)
			printf ("Future income does not exist\nPlease enter again\n");
	}

	printf ("\nEnter the Remark:\n");
	getline(cin,remark);

	timeOfRecord=myDT.getTimeT(date);
	time(&inputTime);

	Income income1(name,amount,timeOfRecord,inputTime,remark);

	printf("\nThe following income has been recorded to the database\n");
	cout<<name<<" "<<floor(amount * 100 + 0.5) / 100<<" "<<timeOfRecord<<" "<<remark<<endl<<endl;
	_curUser->addIncome(income1);
	_curActionManager->addIncomeAction(income1,Add);
	cout << "x : return to main menu" << endl;
}

//@author A0073611N
int Page::printIncomeList(e_dateRange _mDateRange)
{
	string remark,date,input,name=" ";
	double amount=0;
	time_t timeOfRecord=0;
	time_t timeInput=0;
	time_t startTime,endTime;
	list<Income> mylist;
	int number=0;

	switch(_mDateRange)
	{
	case 0:
		{
			printf("Please enter the date <DDMMYYYY>\n");
			getline(cin,date);
			try{
				startTime=myDT.getTimeT(date)-86400;
				endTime=myDT.getTimeT(date);
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			break;
		}
	case 1:
		{
			printf("Please enter the month <MMYYYY>\n");
			getline(cin,date);
			try{
				startTime=myDT.getTimeT("01"+date)-86400;
				endTime=myDT.getNextMonthYear(date)-86400;
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			break;
		}
	case 2:
		{
			printf("Please enter the start time <DDMMYYYY>\n");
			getline(cin,date);
			try{
				startTime=myDT.getTimeT(date)-86400;
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			printf("Please enter the end time <DDMMYYYY>\n");
			getline(cin,date);
			try{
				endTime=myDT.getTimeT(date);
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0;
			}
			break;
		}
	}
	mylist=_curUser->getUserAccount()->readIncome(startTime, endTime); 
	if (mylist.empty())
		printf("No record found, press x to main menu\n");
	else
	{
		printf("------------------------------------------------------------------\n");
		printf("                           Report                                 \n");
		cout<<"          From:"<<myDT.getDate(startTime+86400)<<"               To:"<<myDT.getDate(endTime)<<endl;
		printf("------------------------------------------------------------------\n");
		printf("<no.> <item> <amount> <time> <remark>\n");
		for(list<Income>::iterator it=mylist.begin();it != mylist.end(); ++it)
		{
			name=it->getName();
			amount=it->getAmount();
			timeOfRecord=it->getTimeOfRecord();
			remark=it->getRemark();
			if (number!=mylist.size())
				number++;
			cout<<number<<" "<<name<<" "<<floor(amount * 100 + 0.5) / 100<<" "<<myDT.getDate(timeOfRecord)<<" "<<remark<<endl;
		}
		printf("------------------------------------------------------------------\n");
		cout<<endl;

		printf("u : update income, d : delete income, x : return to main menu\n");
		do{
			getline(cin,input);
		}while(input!="d" && input!="u" && input!="x");
		if(input=="d")
			delIncome(mylist);
		else if(input=="u")
			upIncome(mylist);
		else if(input=="x")
			return -1;
	}
	return 0;
}

//@author A0073611N
void Page::delIncome(list<Income> mylist)
{
	string remark,date,input,name=" ";
	double amount=0;
	time_t timeOfRecord=0;
	time_t timeInput=0;
	Income income(name,amount,timeOfRecord,timeInput,remark);
	int choice,i;

	printf("\nPleaase select the income you want to delete:\n");
	getline(cin, input);
	choice=atoi(input.c_str());
	list<Income>::iterator it2=mylist.begin();
	for(i=0;i<choice-1; i++){
		if(it2 == mylist.end()){
			cout << "x : return to main menu" << endl;
			return;
		}
		it2++;
	}
	income=*it2;
	_curUser->deleteIncome(income);
	_curActionManager->addIncomeAction(income,Delete);

	printf("\nThis income is deleted:\n");
	cout<<income.getName()<<" "<<floor(income.getAmount()*100+0.5)/100<<" "<<myDT.getDate(income.getTimeOfRecord())<<" "<<remark<<endl;
	cout << "x : return to main menu" << endl;
}

//@author A0073611N
void Page::upIncome(list<Income> mylist)
{
	string remark,date,input,name=" ";
	double amount=0;
	time_t timeOfRecord=0;
	time_t timeInput=0;
	Income income(name,amount,timeOfRecord,timeInput,remark);
	int choice,i;

	printf("\nPleaase select the loan you want to update:\n");
	getline(cin, input);
	choice=atoi(input.c_str());
	list<Income>::iterator it2=mylist.begin();
	for(i=0;i<choice-1; i++){
		if(it2 == mylist.end()){
			cout << "x : return to main menu" << endl;
			return;
		}
		it2++;
	}
	income=*it2;
	name=it2->getName();
	amount=it2->getAmount();
	timeInput=it2->getTimeOfInput();
	timeOfRecord=it2->getTimeOfRecord();

	printf("\nThis income is chosen:\n");
	cout<<income.getName()<<" "<<floor(income.getAmount()*100+0.5)/100<<endl;

	printf("\nUpdate Name? <Y/N>\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Name: \n");
		getline(cin,name);
	}

	printf("\nUpdate Amount? <Y/N>\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Amount: \n");
		getline(cin,input);
		istringstream in(input);
		in >>amount;
	}

	printf("\nUpdate Remark? <Y/N>\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");
	if(input=="Y")
	{
		printf("\nInput new Remark: \n");
		getline(cin,remark);
	}


	Income new_income(name,amount,timeOfRecord,timeInput,remark);
	_curUser->updateIncome(income,new_income);
	_curActionManager->addIncomeAction(income,Update);
	_curActionManager->addIncomeAction(new_income,Update);

	printf("\nThis income is updated:\n");
	cout<<new_income.getName()<<" "<<floor(new_income.getAmount()*100+0.5)/100<<" "<<myDT.getDate(new_income.getTimeOfRecord())<<" "<<remark<<endl;
	cout << "x : return to main menu" << endl;
}

//@author A0073611N
int Page::printReport(e_dateRange _mDateRange)
{
	string date,input,name=" ";
	double amount=0;
	time_t timeOfRecord=0;
	time_t timeInput=0;
	e_method method=Cash;
	e_category category=Food;
	string s_method;
	string s_category;
	string remark=" ";
	time_t startTime,endTime;
	list<Expense> mylist_e;
	Expense exp(name,amount,timeOfRecord,timeInput,method,category,remark);
	list<Income> mylist_i;
	Income income(name,amount,timeOfRecord,timeInput,remark);

	switch(_mDateRange)
	{
	case 0:
		{
			printf("Please enter the date <DDMMYYYY>\n");
			getline(cin,date);
			try{
				startTime=myDT.getTimeT(date)-86400;
				endTime=myDT.getTimeT(date);
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0 ;
			}
			break;
		}
	case 1:
		{
			printf("Please enter the month <MMYYYY>\n");
			getline(cin,date);
			try{
				startTime=myDT.getTimeT("01"+date)-86400;
				endTime=myDT.getNextMonthYear(date)-86400;
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0 ;
			}
			break;
		}
	case 2:
		{
			printf("Please enter the start time <DDMMYYYY>\n");
			getline(cin,date);
			try{
				startTime=myDT.getTimeT(date)-86400;
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0 ;
			}
			printf("Please enter the end time <DDMMYYYY>\n");
			getline(cin,date);
			try{
				endTime=myDT.getTimeT(date);
			}
			catch (string e)
			{
				cout << "Error: " << e << endl;
				cout << "x : return to main menu" << endl;
				return 0 ;
			}
			break;
		}
	}

	double balance = 0;

	mylist_e=_curUser->getUserAccount()->readExpense(startTime, endTime);
	mylist_i=_curUser->getUserAccount()->readIncome(startTime, endTime); 
	if (mylist_e.empty()&&mylist_i.empty())
		printf("No record found, press x to main menu\n");
	else
	{
		if(mylist_e.size()!=0)
		{
			printf("------------------------------------------------------------------\n");
			printf("                     Totol Expense Report                         \n");
			cout<<"          From:"<<myDT.getDate(startTime+86400)<<"               To:"<<myDT.getDate(endTime-86400)<<endl;
			printf("------------------------------------------------------------------\n");
			printf("<name> <amount> <date> <category> <method> <remark>\n");
			for(list<Expense>::iterator it=mylist_e.begin();it != mylist_e.end(); ++it)
			{
				name=it->getName();
				amount=it->getAmount();
				timeOfRecord=it->getTimeOfRecord();
				s_method=methodEnumtoString(it->getMethod());
				s_category=categoryEnumtoString(it->getCategory());
				remark=it->getRemark();
				cout<<name<<"\t"<<floor(amount* 100 + 0.5) / 100<<"\t"<<myDT.getDate(timeOfRecord)<<"\t"<<s_category<<"\t"<<s_method<<"\t"<<remark<<endl;
				balance -= amount;
			}
			printf("------------------------------------------------------------------\n");
			cout<<endl;
		}

		if(mylist_i.size()!=0)
		{
			printf("------------------------------------------------------------------\n");
			printf("                      Total Income Report                         \n");
			cout<<"          From:"<<myDT.getDate(startTime+86400)<<"               To:"<<myDT.getDate(endTime-86400)<<endl;
			printf("------------------------------------------------------------------\n");
			printf("<name> <amount> <time> <remark>\n");

			for(list<Income>::iterator it=mylist_i.begin();it != mylist_i.end(); ++it)
			{
				name=it->getName();
				amount=it->getAmount();
				timeOfRecord=it->getTimeOfRecord();
				remark=it->getRemark();
				cout<<name<<" "<<floor(amount * 100 + 0.5) / 100<<" "<<myDT.getDate(timeOfRecord)<<" "<<remark<<endl;
				balance += amount;
			}
			printf("------------------------------------------------------------------\n");
			cout<<endl;
		}
		cout << "Balance: $" << floor(balance * 100 + 0.5) / 100 << endl;

		printf("e : export expense, x : return to main menu\n");
		do{
			getline(cin,input);
		}while(input!="e" && input!="x");
		if(input=="e")
			expReport(mylist_e,mylist_i);
		else if(input=="x")
			return -1;
	}
	return 0;
}

//@author A0073611N
void Page::expReport(list<Expense> mylist_e,list<Income> mylist_i)
{
	ofstream MyExcelFile;
	time_t t;
	int filenameT;
	//string filename;
	stringstream filename;//create a stringstream

	time(&t);
	filenameT= (int) t;
	filename<<"Report "<<filenameT<<".csv";

	MyExcelFile.open(filename.str());

	double balance = 0;

	if (mylist_e.empty()&&mylist_i.empty())
		printf("No record found, press x to main menu\n");
	else
	{
		if(mylist_e.size()!=0)
		{
			MyExcelFile << "Expense" <<endl;
			MyExcelFile << "Item, Amount, Expense Date, Method, Category, Remark" << endl;
			for(list<Expense>::iterator it=mylist_e.begin(); it != mylist_e.end(); it++){
				MyExcelFile <<it->getName()<<","<<floor(it->getAmount()*100+0.5)/100<<","<<myDT.getDate(it->getTimeOfRecord())<<","<<methodEnumtoString(it->getMethod())<<","<<categoryEnumtoString(it->getCategory())<<","<<it->getRemark()<< endl;
				balance -= it->getAmount();
			}
		}
		if(mylist_i.size()!=0)
		{
			MyExcelFile << "Income" <<endl;
			MyExcelFile << "Item, Amount,Time,Remark"<<endl;
			for(list<Income>::iterator it=mylist_i.begin();it != mylist_i.end(); ++it){
				MyExcelFile<<it->getName()<<","<<floor(it->getAmount()*100+0.5)/100<<","<<myDT.getDate(it->getTimeOfRecord())<<","<<it->getRemark() << endl;
				balance += it->getAmount();
			}
		}
		MyExcelFile<<"Balance,"<<balance << endl;
	}
	MyExcelFile.close();
	cout<<"The report is generated, with file name: "<<filename.str()<<endl;
	cout << "x : return to main menu" << endl;
}

//@author U095387X
void Page::updateUser(){

	string input, name, sbudget, sCashOnHand;

	printf("\nUpdate Name? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");

	if(input=="Y"){
		printf("Please enter your name:");
		getline(cin,name);
		_curUser->updateName(name);
	}

	printf("\nUpdate monthly budget? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");

	if(input=="Y"){
		printf("Please enter your monthly budget:");
		getline(cin,sbudget);
		_curUser->updateBudget(atof(sbudget.c_str()));
	}

	printf("\nUpdate Cash on hand? [Y/N]\n");
	do{
		getline(cin,input);
	}while(input !="Y" && input !="N");

	if(input=="Y"){
		printf("Please enter your cash on hand:");
		getline(cin,sCashOnHand);
		_curUser->updateCashOnHand(atof(sCashOnHand.c_str()));
	}

	_curUser->saveUser();
	cout << "The changes have been saved." << endl;
	cout << "x : return to main menu" << endl;
	return;
}

//@author A0073611N
bool Page::impReport()
{
	string filename;

	deque <string> data;
	string s;
 	string input,name,remark;
	double amount;
	time_t timeOfRecord;
	time_t inputTime;
	string date,mMethod,mCategory;
	e_method e_met;
	e_category e_cat;
	time(&inputTime);

  int i=0,j=0;

	cout << "Please enter the file name to read:> ";
	getline( cin, filename );
	ifstream f( filename.c_str() );

  while (getline( f, s ))
  {
	  if(j>=1)
	  {
		  if(j==2)
		  {
		  	vector<std::string> result = explode(s, ',');
			vector<std::string>::iterator it=result.begin();
			while(it!=result.end())
			{
				name=*(it++);
				amount=stol(*(it++));
				timeOfRecord=myDT.getTimeT(*(it++));
				remark=*(it++);
			}
			Income inc(name,amount,timeOfRecord,inputTime,remark);
			_curUser->addIncome(inc);
			_curActionManager->addIncomeAction(inc,Add);
		  }
		  j++;
	  }
	  if((i>1)&&(j==0))
	  {
		  if(s!="Income")
		  {
			vector<std::string> result = explode(s, ',');
			vector<std::string>::iterator it=result.begin();
			while(it!=result.end())
			{
				name=*(it++);
				amount=stol(*(it++));
				timeOfRecord=myDT.getTimeT(*(it++));

				mMethod=*(it++);
				if(mMethod=="Cash")
					e_met=Cash;
				else if(mMethod=="CreditCard")
					e_met=CreditCard;
				else if(mMethod=="DebitCard")
					e_met=DebitCard;

				mCategory=*(it++);
				if(mCategory=="Food")
					e_cat=Food;
				else if(mCategory=="Transportation")
					e_cat=Transportation;
				else if(mCategory=="Entertainment")
					e_cat=Entertainment;
				else if(mCategory=="Others")
					e_cat=Others;

				remark=*(it++);
			}
			Expense exp(name,amount,timeOfRecord,inputTime,e_met,e_cat,remark);
			_curUser->addExpense(exp);
			_curActionManager->addExpenseAction(exp,Add);
		  }
		  else if(s=="Income")
			  j=1;
	  }
	  i++;
  }
  printf("\nAll records have been imported to the program!\npress x to main menu\n");
  return f.good();
  }
